package cn.elwy.rcp.ui.handler;

import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Shell;

/**
 * 窗口移到顶部，自动隐藏窗口
 * 
 * @author huangsq
 * @version 1.0, 2013-11-20
 * @since 1.0, 2013-11-20
 */
public class AutoHideShell {
  private Shell shell;
  private static final int WIDTH = 5;
  private boolean isHidden = false;

  /**
   * 注意shell的样式需要添加SWT.ON_TOP保证shell最前显示
   * 
   * @param shell
   */
  public AutoHideShell(Shell shell) {
    this.shell = shell;
  }

  public void addListener() {
    shell.addControlListener(controlListener);
    shell.addMouseMoveListener(mouseMoveListener);
    // shell.addShellListener(shellListener);
  }

  public void removeListener() {
    shell.removeControlListener(controlListener);
    shell.removeMouseMoveListener(mouseMoveListener);
    // shell.removeShellListener(shellListener);
  }

  ControlListener controlListener = new ControlAdapter() {
    public void controlMoved(ControlEvent e) {
      Shell shell = (Shell) e.widget;
      Rectangle rect = shell.getBounds();
      if (rect.y < 1 && !isHidden) {
        shell.setLocation(rect.x, WIDTH - rect.height);
        isHidden = true;
      } else if (rect.y > 1 && isHidden) {
        isHidden = false;
      }
    }
  };

  /**
   * 不用MouseTrackListener的mouseEnter()，而是在MouseMoveListener判断鼠标是否进入shell理由：
   * 假如使用mouseEnter()，那么在该方法内调用Shell的setLocation() 可能造成原来的鼠标位置不在shell内， 从而触发mouseExit()，该方法又将shell停靠隐藏。
   */
  MouseMoveListener mouseMoveListener = new MouseMoveListener() {
    public void mouseMove(MouseEvent e) {
      Shell shell = (Shell) e.widget;
      Rectangle rect = shell.getBounds();
      Point p = shell.getDisplay().getCursorLocation();
      if (isHidden && rect.contains(p) && rect.y <= 0) {
        shell.setLocation(rect.x, 0);
        // 注意这里
        shell.addMouseTrackListener(mouseTrackListener);
      }
    }
  };
  MouseTrackListener mouseTrackListener = new MouseTrackAdapter() {
    public void mouseExit(MouseEvent e) {
      Shell shell = (Shell) e.widget;
      if (e.widget == shell && isHidden) {
        Rectangle rect = shell.getBounds();
        shell.setLocation(rect.x, WIDTH - rect.height);
        // 注意这里
        shell.removeMouseTrackListener(mouseTrackListener);
      }
    }
  };

  // 不允许最小化，保证点击任务栏上的"显示桌面"时，shell依然在最前显示
  ShellListener shellListener = new ShellAdapter() {
    public void shellIconified(ShellEvent e) {
      Shell shell = (Shell) e.widget;
      shell.setMinimized(false);
    }
  };

}
